home *** CD-ROM | disk | FTP | other *** search
/ Meeting Pearls 1 / Meeting Pearls Vol 1 (1994).iso / installed_progs / gfx / lise2.1 / lise / src / ash.c next >
Encoding:
C/C++ Source or Header  |  1993-03-31  |  16.9 KB  |  635 lines

  1. /* This program draws a spectrum, possibly with error bars
  2.    possible parameters:
  3.    ash sp[1:1024] {-y 0} {+y 1000} {-b} {-v} {-c}
  4.        sp[min:max] specifies spectrum name and range (default is stdin)
  5.        -y %E specifies the lower bound
  6.        +y %E specifies the upper bound
  7.        -lx logarithmic x-scale
  8.        -ly logarithmic y-scale
  9.        -grid draw grid
  10.        -d display only (don't draw axis)
  11.        -xn don't print x-axis numbers
  12.        -yn don't print y-axis numbers
  13.        -xi x-axis numbers are integers
  14.        -yi y-axis numbers are integers
  15.        -xf x-axis numbers in format a.b
  16.        -yf y-axis numbers in format a.b
  17.        -xe x-axis numbers in format a.bEn
  18.        -ye y-axis numbers in format a.bEn
  19.        -x2 only print every second x number
  20.        -pag clear screen before drawing
  21.        -use use old parameters
  22.        -cur prints cursor position after drawing
  23.        -b draws error bars \
  24.        -v draws vectors     - default is point only
  25.        -c draws circles    /
  26.    The boundaries of the real data area of the screen are saved
  27.    to /tmp/ashbdry as ASCII integers
  28.  
  29.                                           Programmer: RAKO
  30. */
  31.  
  32. #include <stdio.h>
  33. #ifdef AMIGA
  34. #include <gfxamiga.h>
  35. #include <workbench/workbench.h>
  36. #include <workbench/startup.h>
  37. #include <workbench/icon.h>
  38. extern struct WBStartup *WBenchMsg;
  39. extern struct IconBase *IconBase;
  40. #endif
  41. #ifdef UNIX
  42. #include <gfx.h>
  43. #endif
  44.  
  45. char  xfmt[20], yfmt[20];
  46.  
  47. int   dot_flg=TRUE,
  48.       bar_flg=FALSE,
  49.       vec_flg=FALSE,
  50.       point_style=0,
  51.       point_size=0,
  52.       logx=FALSE,
  53.       logy=FALSE,
  54.       vecpos=0;
  55. int   flag_xnum = 1,
  56.       flag_ynum = 1,
  57.       flag_grid = 0,
  58.       xn_count = 0;
  59. int   leftmargin = 520,
  60.       bottommargin = 120,
  61.       rightmargin = _TEKXMAX-120,
  62.       topmargin = _TEKYMAX-120;
  63. int   reversex = 0,
  64.       reversey = 0;
  65. float *spc,*err,*tim;
  66.  
  67. help()
  68. {
  69. printf("Draw a spectrum with axis\n");
  70. printf(" possible parameters:\n");
  71. printf(" ash sp[1:1024] {-y 0} {+y 1000} {-b} {-v} {-c}\n");
  72. printf("  sp[min:max] specifies spectrum name and range (default is stdin)\n");
  73. printf("  -y n.m    specifies the lower bound\n");
  74. printf("  +y n.m    specifies the upper bound\n");
  75. printf("  -x n.m    specifies starting x\n");
  76. printf("  +x n.m    specifies last x\n");
  77. printf("  -bnmr     leaves space between axis and first/last point\n");
  78. printf("  -lx       logarithmic x-scale\n");
  79. printf("  -ly       logarithmic y-scale\n");
  80. printf("  -d        display only (don't draw axis)\n");
  81. printf("  -grid     draw a grid\n");
  82. printf("  -zero     draw a horizontal line at y=0\n");
  83. printf("  -xn       don't print x-axis numbers\n");
  84. printf("  -yn       don't print y-axis numbers\n");
  85. printf("  -cn       don't print comment\n");
  86. printf("  -rx       reverse x numbering\n");
  87. printf("  -ry       reverse y numbering\n");
  88. printf("  -xi       x-axis numbers are integers\n");
  89. printf("  -yi       y-axis numbers are integers\n");
  90. printf("  -xf       x-axis numbers in format a.b\n");
  91. printf("  -yf       y-axis numbers in format a.b\n");
  92. printf("  -xe       x-axis numbers in format a.bEn\n");
  93. printf("  -ye       y-axis numbers in format a.bEn\n");
  94. printf("  -x%% cfmt  x-axis numbers in FLOAT C format cfmt (needs additional %)\n");
  95. printf("  -y%% cfmt  y-axis numbers in FLOAT C format cfmt (needs additional %)\n");
  96. printf("  -x2       only print every second x number\n");
  97. printf("  -pag      clear screen before drawing\n");
  98. printf("  -use      use old parameters\n");
  99. printf("  -cur      prints cursor position after drawing\n");
  100. printf("  -b        draws error bars \\\n");
  101. printf("  -v        draws vectors     - default is point only\n");
  102. printf("  -c        draws circles    /\n");
  103. printf("  -cir n    draws circles with radius n.m\n");
  104. printf("  -crf n    draws filled circles with radius n\n");
  105. printf("  -tri n    draws triangles with baseline n (negative n gives\n");
  106. printf("                                            inverted triangles)\n");
  107. printf("  -trf n    draws filled triangles with baseline n\n");
  108. printf("  -qua n    draws quadrates with baseline n\n");
  109. printf("  -qaf n    draws filled quadrates with baseline n\n");
  110. printf("  -mb n     defines bottom margin\n");
  111. printf("  -mt n     defines top margin\n");
  112. printf("  -mr n     defines right margin\n");
  113. printf("  -ml n     defines left margin\n");
  114.    return(0);
  115. }
  116.  
  117. minimax(spc,xmax,min,max)
  118. float spc[],*min,*max;
  119. int   xmax;
  120. {  /* findig maximum and minimum of spectrum */
  121. int n;
  122.    *max = spc[0]; *min = spc[0];
  123.    for(n=0;n<xmax;n++) {
  124.       if(spc[n] > *max) *max = spc[n];
  125.       if(spc[n] < *min) *min = spc[n];
  126.    }
  127.    if((*max == 0.0) && (*min == 0.0)) {
  128.       *min = -1.0; *max = 1.0;
  129.    }
  130.    return(0);
  131. }
  132.  
  133. disp(y,e,t)       /* plot a point in the window */
  134. float y,e,t;
  135. {
  136. int   n,xx,yy,ee;
  137. float fx1,fx2,fy1,fy2,fr,phi,finc;
  138.  
  139.    xx=t; yy=y; ee=e;
  140.    if((y < bottommargin) || (y > topmargin)) return(0);
  141.    if((xx < leftmargin) || (xx > rightmargin)) return(0);
  142.    if(dot_flg) {
  143.       posita(xx,yy); vectoa(xx,yy);
  144.    }
  145.    if(bar_flg) {
  146.       posita(xx,yy-ee); vectoa(xx,yy+ee);
  147.       posita(xx,yy);
  148.    }
  149.    if(vec_flg) {
  150.    if(vecpos==0) {
  151.          vecpos=1;
  152.          posita(xx,yy);
  153.       }
  154.       vectoa(xx,yy);
  155.    }
  156.    switch(point_style) {
  157.    case 0:
  158.       return(0);
  159.       break;
  160.    case 1:     /* circle */
  161.       fr=point_size;
  162.       xx = t ; yy = y+fr; posita(xx,yy);
  163.       finc=1.57079/fr;
  164.       phi=finc;
  165.       fx1=0; fy1=fr;
  166.       for(n=0; n < (4*point_size); n++) {
  167.          fx2=fr*sin(phi); fy2=fr*cos(phi);
  168.          xx = t + fx2; yy = y + fy2; vectoa(xx,yy);
  169.          phi=phi+finc;
  170.       }
  171.       xx=t; yy=y; posita(xx,yy);
  172.       break;
  173.    case 2:     /* filled circle */
  174.       fr=point_size;
  175.       phi=0.0;
  176.       finc=1.57079/fr;
  177.       fx1=0; fy1=fr;
  178.       for(n=0;n <= (point_size + 1);n++) {
  179.          fx2=fr*sin(phi); fy2=fr*cos(phi);
  180.          xx=(t+fx1); yy=(y+fy1); posita(xx,yy);
  181.          xx=(t-fx1); vectoa(xx,yy);
  182.          yy=(y-fy1); posita(xx,yy);
  183.          xx=(t+fx1); vectoa(xx,yy);
  184.          fx1=fx2; fy1=fy2;
  185.          phi=phi+finc;
  186.       }
  187.       xx=t; yy=y; posita(xx,yy);
  188.       break;
  189.    case 3:     /* triangle */
  190.       xx=t+point_size; yy=y-point_size; posita(xx,yy);
  191.       xx=t-point_size; vectoa(xx,yy);
  192.       yy=y+point_size; xx=t; vectoa(xx,yy);
  193.       xx=t+point_size; yy=y-point_size; vectoa(xx,yy);
  194.       xx=t; yy=y; posita(xx,yy);
  195.       break;
  196.    case 4:     /* filled triangle */
  197.       xx=t-point_size;
  198.       for(n=0;n<(2*point_size);n++) {
  199.          yy=y+point_size; posita((int)t,yy);
  200.          yy=y-point_size; vectoa(xx,yy);
  201.          xx=xx+1;
  202.       }
  203.       xx=t; yy=y; posita(xx,yy);
  204.       break;
  205.    case 5:     /* quadrate */
  206.       xx=t+point_size; yy=y-point_size; posita(xx,yy);
  207.       xx=t-point_size; vectoa(xx,yy);
  208.       yy=y+point_size; vectoa(xx,yy);
  209.       xx=t+point_size; vectoa(xx,yy);
  210.       yy=y-point_size; vectoa(xx,yy);
  211.       xx=t; yy=y; posita(xx,yy);
  212.       break;
  213.    case 6:     /* filled quadrate */
  214.       yy=y-point_size;
  215.       for(n=0;n<(2*point_size);n++) {
  216.          xx=t+point_size; posita(xx,yy);
  217.          xx=t-point_size; vectoa(xx,yy);
  218.          yy=yy+1;
  219.       }
  220.       xx=t; yy=y; posita(xx,yy);
  221.       break;
  222.    }
  223. }
  224.  
  225. float slog(x)
  226. float x;
  227. {
  228. float erg;
  229. erg = 0.0;
  230. if( x > 0.0) erg = log(x);  /* / 2.3026; */
  231. return(erg);
  232. }
  233.  
  234. float pow10intlog10(x) /* same as n=pow(10,floor(log10( (double)d + 1.0E-10))) */
  235. float x;
  236. {
  237. float xx;
  238.  
  239.    xx=1.0;
  240.    if(x > 1.0) {
  241.       while(xx < x) xx = xx * 10.0;
  242.       xx = xx / 10.0;
  243.    }
  244.    if(x < 1.0) {
  245.       while(xx > x) xx = xx / 10.0;
  246.    }
  247.    return(xx);
  248. }
  249.  
  250.  
  251. main(argc,argv)
  252. int argc;
  253. char *argv[];
  254. {
  255. int   n,xmax;
  256. float x,
  257.       ymax = 1.0,
  258.       ymin = 0.0,
  259.       yfak = 1.0,
  260.       tmin = 0.0,
  261.       tmax = _MAXSPCLEN,
  262.       tfak = 1.0,
  263.       xoffset = 0,
  264.       yoffset = 0;
  265. char  *z,*comment;
  266. double ftmp;
  267. FILE  *fp;
  268. #ifdef AMIGA
  269. struct WBArg *Arg;
  270. #endif
  271.  
  272.    z = (char *) malloc(80);
  273.    comment = (char *) malloc(80);
  274.  
  275.    checkopt(argc,argv,"-dummy",z);
  276.  
  277.    spc= (float *)calloc(_MAXSPCLEN+2,sizeof(float));
  278.    err= (float *)calloc(_MAXSPCLEN+2,sizeof(float));
  279.    tim= (float *)calloc(_MAXSPCLEN+2,sizeof(float));
  280.    if(tim==NULL) {
  281.       printf("sorry, not enough memory\n");
  282.       exit(-1);
  283.    }
  284.  
  285.    if(argc > 1) strcpy(z,argv[1]);
  286.    xmax=readspec(z,spc,err,tim,comment);
  287. /* findig maximum and minimum of spectrum */
  288.    minimax(spc,xmax,&ymin,&ymax);
  289.    if(ymax < 0.0) {
  290.       ymax = 0.9 * ymax;
  291.    } else {
  292.       ymax = 1.1 * ymax;
  293.    }
  294.    if(ymin < 0.0)  {
  295.       ymin = 1.1 * ymin;
  296.    } else {
  297.       ymin = 0.9 * ymin;
  298.    }
  299.    minimax(tim,xmax,&tmin,&tmax);
  300.  
  301.  
  302.    if(checkopt(argc,argv,"-use",z)) {
  303.       fp=fopen(ASHBDRY,"r");
  304.       if(fp == NULL) {
  305.          printf("%s not found!\n",ASHBDRY);
  306.          exit(0);
  307.       }
  308.       fscanf(fp,"%d\n%d\n%d\n",&leftmargin,&bottommargin,&rightmargin);
  309.       fscanf(fp,"%d\n%d\n",&topmargin,&_win_flg);
  310.       fscanf(fp,"%lf\n",&ftmp); tmin = (float) ftmp;
  311.       fscanf(fp,"%lf\n",&ftmp); tmax = (float) ftmp;
  312.       fscanf(fp,"%lf\n",&ftmp); ymin = (float) ftmp;
  313.       fscanf(fp,"%lf\n",&ftmp); ymax = (float) ftmp;
  314.       fclose(fp);
  315.    }
  316.  
  317.    if(checkopt(argc,argv,"-bnmr",z)) {
  318.       x = 0.05 * (tmax - tmin);
  319.       tmin = tmin - x;
  320.       tmax = tmax + x;
  321.    }
  322.    if(checkopt(argc,argv,"-grid",z)) flag_grid = 1;
  323.    if(checkopt(argc,argv,"-zero",z)) flag_grid = 2;
  324.    if(checkopt(argc,argv,"-lx",z)) logx=TRUE;
  325.    if(checkopt(argc,argv,"-ly",z)) logy=TRUE;
  326.    flag_xnum = 1; flag_ynum = 1;
  327.    if(checkopt(argc,argv,"-xn",z)) flag_xnum = 0;
  328.    if(checkopt(argc,argv,"-yn",z)) flag_ynum = 0;
  329.    if(checkopt(argc,argv,"-xf",z)) flag_xnum = 2;
  330.    if(checkopt(argc,argv,"-yf",z)) flag_ynum = 2;
  331.    if(checkopt(argc,argv,"-xe",z)) flag_xnum = 3;
  332.    if(checkopt(argc,argv,"-ye",z)) flag_ynum = 3;
  333.    if(checkopt(argc,argv,"-xi",z)) flag_xnum = 4;
  334.    if(checkopt(argc,argv,"-yi",z)) flag_ynum = 4;
  335.    if(checkopt(argc,argv,"-x%",xfmt)) flag_xnum = 5;
  336.    if(checkopt(argc,argv,"-y%",yfmt)) flag_ynum = 6;
  337.    reversex = 0; if(checkopt(argc,argv,"-rx",z)) reversex = 1;
  338.    reversey = 0; if(checkopt(argc,argv,"-ry",z)) reversey = 1;
  339.    if(checkopt(argc,argv,"-x2",z)) xn_count = -1;
  340.  
  341.    if(checkopt(argc,argv,"-y",z)) ymin=atosf(z);
  342.    if(checkopt(argc,argv,"+y",z)) ymax=atosf(z);
  343.    if(checkopt(argc,argv,"-x",z)) tmin=atosf(z);
  344.    if(checkopt(argc,argv,"+x",z)) tmax=atosf(z);
  345.    if(checkopt(argc,argv,"-b",z)) {
  346.       dot_flg=FALSE;
  347.       bar_flg=TRUE;
  348.    }
  349.    if(checkopt(argc,argv,"-v",z)) {
  350.       dot_flg=FALSE;
  351.       vec_flg=TRUE;
  352.    }
  353.    if(checkopt(argc,argv,"-c",z)) {
  354.       dot_flg=FALSE;
  355.       point_style=1;
  356.       point_size=16;
  357.    }
  358.    if(checkopt(argc,argv,"-cir",z)) {
  359.       dot_flg=FALSE;
  360.       point_style=1;
  361.       point_size=atoi(z);
  362.    }
  363.    if(checkopt(argc,argv,"-crf",z)) {
  364.       dot_flg=FALSE;
  365.       point_style=2;
  366.       point_size=atoi(z);
  367.    }
  368.    if(checkopt(argc,argv,"-tri",z)) {
  369.       dot_flg=FALSE;
  370.       point_style=3;
  371.       point_size=atoi(z);
  372.    }
  373.    if(checkopt(argc,argv,"-trf",z)) {
  374.       dot_flg=FALSE;
  375.       point_style=4;
  376.       point_size=atoi(z);
  377.    }
  378.    if(checkopt(argc,argv,"-qua",z)) {
  379.       dot_flg=FALSE;
  380.       point_style=5;
  381.       point_size=atoi(z);
  382.    }
  383.    if(checkopt(argc,argv,"-qaf",z)) {
  384.       dot_flg=FALSE;
  385.       point_style=6;
  386.       point_size=atoi(z);
  387.    }
  388.    if(checkopt(argc,argv,"-mt",z)) topmargin = atoi(z);
  389.    if(checkopt(argc,argv,"-mb",z)) bottommargin = atoi(z);
  390.    if(checkopt(argc,argv,"-ml",z)) leftmargin = atoi(z);
  391.    if(checkopt(argc,argv,"-mr",z)) rightmargin = atoi(z);
  392.    
  393.    tekopen();
  394.  
  395.    if(checkopt(argc,argv,"-pag",z)) dperas();
  396.  
  397. #ifdef AMIGA
  398.    if(argc == 0) {
  399.       IconBase = (struct IconBase *) OpenLibrary("icon.library", 0L);
  400.       Arg = WBenchMsg->sm_ArgList; Arg++;
  401.       CurrentDir(Arg->wa_Lock);
  402.       strcpy(z,Arg->wa_Name);
  403.       if(strlen(z) < 2) exit(0);
  404.       dperas();
  405.    }
  406. #endif
  407.  
  408.    if(logy) {
  409.       for(n=0;n<xmax;n++) {
  410.          spc[n] = slog(spc[n]);
  411.          err[n] = slog(err[n]);
  412.       }
  413.    ymin = slog(ymin);
  414.    ymax = slog(ymax);
  415.    }
  416.  
  417.    if(logx) {
  418.       for(n=0;n<xmax;n++) {
  419.          tim[n] = slog(tim[n]);
  420.       }
  421.    tmin = slog(tmin);
  422.    tmax = slog(tmax);
  423.    }
  424.  
  425.    yfak=(topmargin-bottommargin)/(ymax-ymin);
  426.    tfak=(rightmargin-leftmargin)/(tmax-tmin);
  427.    xoffset= ((- tmin) * tfak) + leftmargin;
  428.    yoffset= ((- ymin) * yfak) + bottommargin;
  429.    if(reversex == 1) {
  430.       xoffset = leftmargin + (tmax * tfak);
  431.       tfak = -1 * tfak;
  432.    }
  433.    if(reversey == 1) {
  434.       yoffset = bottommargin + (ymax * yfak);
  435.       yfak = -1 * yfak;
  436.    }
  437.  
  438.    if(!checkopt(argc,argv,"-d",z)) {
  439.       axis(leftmargin,bottommargin,rightmargin,topmargin,tmin,tmax,ymin,ymax);
  440.    }
  441.    for(n=0;n<xmax;n++) {
  442.       disp(spc[n] * yfak + yoffset , err[n] * yfak , tim[n] * tfak + xoffset);
  443.    }
  444.  
  445.    if((!checkopt(argc,argv,"-d",z)) && (!checkopt(argc,argv,"-cn",z))) {
  446.       posita(leftmargin+80,topmargin+32);
  447.       gfxtext(comment,0.0);
  448.    }
  449.    gfxflush();
  450.  
  451.    unlink(ASHBDRY);
  452.    /* print out boundaries of usable data area */
  453.    fp=fopen(ASHBDRY,"w");
  454.    fprintf(fp,"%d\n%d\n%d\n",leftmargin,bottommargin,rightmargin);
  455.    fprintf(fp,"%d\n%d\n%E\n",topmargin,_win_flg,tmin);
  456.    fprintf(fp,"%E\n%E\n%E\n",tmax,ymin,ymax);
  457.    fprintf(fp,"%E\n",_tica);
  458.    fclose(fp);
  459.    close(_tek4014);
  460.    free(z); free(comment);
  461.    free(spc); free(err); free(tim);
  462.    return(0);
  463. }
  464.  
  465. /* ----------------------------------------------------------------------
  466.    Draw axis and numbers
  467.    ---------------------------------------------------------------------- */
  468.  
  469. prettystr1(s,x,flag) /* generate string from fp number */
  470. char s[];
  471. float x;
  472. int flag;
  473. {
  474. int ix,fx;
  475. int i,l;
  476.  
  477.    if(flag == 5) {sprintf(s,xfmt,x); return(0);}
  478.    if(flag == 6) {sprintf(s,yfmt,x); return(0);}
  479.    if(flag == 0) {s[0] = 0; return(0);}
  480.    if(flag == 4) {fx = (x + 0.4); sprintf(s,"%-d",fx); return(0);}
  481.    if(flag == 3) {sprintf(s,"%-1.1E",x); return(0);}
  482.    sprintf(s,"%-3.5f",x);
  483.    l = strlen(s) - 1;
  484.    if(instr(".",s) >= 0) while(s[l] == '0') s[l--] = 0;
  485.    if(flag == 2) return(0);
  486.    ix=x; fx=ix; if((x - fx) == 0.0) sprintf(s,"%-d",ix);
  487.    if(fabs(x) < 0.001) sprintf(s,"%-.3E",x);
  488.    if(fabs(x) > 99999.999) sprintf(s,"%-1.1E",x);
  489.    if(fabs(x)<1.0E-6) strcpy(s,"0");
  490.    while(s[0] < 33) {
  491.        l = strlen(s);
  492.        for(i = 0; i <= l; i++) s[i] = s[i+1];
  493.    }
  494.    return(0);
  495. }
  496.  
  497. prettystr(s,x,flag)
  498. char s[];
  499. float x;
  500. int flag;
  501. {
  502. int i,n;
  503. char *z1, *z2;
  504.  
  505.    prettystr1(s,x,flag);
  506.  
  507.    z1 = (char *) malloc(80);
  508.    z2 = (char *) malloc(80);
  509.  
  510.    n = instr("E",s);
  511.    if(n > 0) {
  512.       if(xn_count == 0) xn_count = 1;
  513.       midstr(z1,s,0,n-1);
  514.       midstr(z2,s,n+1,strlen(s));
  515.       i = atoi(z2);
  516.       sprintf(s,"%s\\u . \\d10\\u%d\\d",z1,i);
  517.    }
  518.    free(z1); free(z2);
  519.    return(0);
  520. }
  521.  
  522. axis(sx,sy,ex,ey,xmin,xmax,ymin,ymax) /* draw frame, ticks aand numbers */
  523. int sx,sy,ex,ey;
  524. float xmin,xmax,ymin,ymax;
  525. {
  526. int x,y,lx2;
  527. int txth, txth1;
  528. float nx,ny,ninc;
  529. char *s;
  530.  
  531.    s = (char *) malloc(256);
  532.  
  533.    txth = textheight();
  534.    txth1 = txth + 30;
  535.  
  536.    /* draw frame */
  537.    posita(sx,sy);
  538.    vectoa(ex,sy);
  539.    vectoa(ex,ey);
  540.    vectoa(sx,ey);
  541.    vectoa(sx,sy);
  542.  
  543.    x = (sx + ex) / 2; y = (sy + ey) / 2;
  544.       
  545.    calcnums(xmin,xmax,&nx,&ninc);
  546.    if(logx) nx = pow10intlog10(xmin);
  547.    while((x < (ex + 1)) && (x > (sx - 1))) {
  548.       x = sx + ((ex-sx) * ((nx-xmin)/(xmax-xmin)));
  549.       if(logx) x = sx + ((ex-sx) * ((slog(nx)-xmin)/(xmax-xmin)));
  550.       if(reversex == 1) x = ex - ((ex-sx) * ((nx-xmin)/(xmax-xmin)));
  551.       if((x>ex) || (x<sx)) break;
  552.       posita(x,sy);
  553.       if(flag_grid == 1) {
  554.          vectoa(x,ey);
  555.       } else {
  556.          vectoa(x,sy+20);
  557.          posita(x,ey); vectoa(x,ey-20);
  558.       }
  559.       xn_count = -1 * xn_count;
  560.       if(xn_count >= 0) {
  561.          prettystr(s,nx,flag_xnum);
  562.          lx2 = textlen(s) >> 1;
  563.          if((x + lx2) < rightmargin) {
  564.             posita(x - lx2,sy - txth1);
  565.             gfxtext(s,0.0);
  566.          }
  567.       }
  568.       if(logx) {
  569.          if(nx == 0) nx = 0.1;
  570.          nx = nx * 10;
  571.       } else {
  572.          nx = nx + ninc;
  573.       }
  574.     }
  575.  
  576.    calcnums(ymin,ymax,&ny,&ninc);
  577.    if(logy) ny = pow10intlog10(ymin);
  578.    while((y < (ey + 1)) && (y > (sy -1))) {
  579.       y = sy + ((ey-sy) * ((ny-ymin)/(ymax-ymin)));
  580.       if(logy) y = sy + ((ey-sy) * ((slog(ny)-ymin)/(ymax-ymin)));
  581.       if(reversey == 1) y = ey - ((ey-sy) * ((ny-ymin)/(ymax-ymin)));
  582.       if((y>ey) || (y<sy)) break;
  583.       posita(sx,y);
  584.       if(flag_grid == 1) {
  585.          vectoa(ex,y);
  586.       } else {
  587.          vectoa(sx+20,y);
  588.          posita(ex,y); vectoa(ex-20,y);
  589.       }
  590.       if((fabs(ny) < 0.0001) && (flag_grid == 2)) {
  591.          posita(sx,y);
  592.          vectoa(ex,y);
  593.       }
  594.       prettystr(s,ny,flag_ynum);
  595.       x = sx - textlen(s) - 20;
  596.       if(x < 0 ) x = 1;
  597.       posita(x,y - (txth1 >> 1));
  598.       gfxtext(s,0.0);
  599.       if(logy) {
  600.          if(ny == 0) ny = 0.1;
  601.          ny = ny * 10;
  602.       } else {
  603.          ny = ny + ninc;
  604.       }
  605.    }
  606.    free(s);
  607.    return(0);
  608. }
  609.  
  610.  
  611. calcnums(min,max,ny,ninc) /* calculate increment for axis numbers */
  612. float min,max,*ny,*ninc;
  613. {
  614. float d,n;
  615. int m;
  616.  
  617.    d=fabs(max-min);
  618.    n=pow10intlog10(d);
  619.    m=d/n;
  620.    switch(m) {
  621.    case 1:
  622.       *ninc=n/10;
  623.       break;
  624.    case 2:
  625.       *ninc=n/4;
  626.       break;
  627.    default:
  628.       *ninc=n;
  629.       break;
  630.    }
  631.    *ny=n * floor(min/n);
  632.    while(*ny < min) *ny = *ny + *ninc;
  633.    if((d / *ninc) > 10.0) *ninc = *ninc * 2;
  634.    return(0);
  635. }